﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;
using System.Xml;
namespace AppDesigner.XamlDom
{
    /// <summary>
    /// Xaml Paser Util
    /// </summary>
    public class XamlParser
    {
        #region Sigleton

        private static XamlParser _instance;

        private XamlParser()
        {
            AssemblyLoader.RegisterAssembly(typeof(MarkupExtension).Assembly);  // WindowsBase
            AssemblyLoader.RegisterAssembly(typeof(IAddChild).Assembly);  // PresentationCore
            AssemblyLoader.RegisterAssembly(typeof(XamlReader).Assembly); // PresentationFramework
        }

        public static XamlParser Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new XamlParser();
                }
                return _instance;
            }
        }

        #endregion
        

        #region Fields

        private XamlParserSettings _settings;
        private XmlSpace _currentXmlSpace = XmlSpace.None;
        private XamlObject _currentXamlObject;
        private XamlDocument _document;

        #endregion
        
        #region Properties

        public IXamlErrorService XamlErrorService
        {
            get
            {
                if (_settings == null)
                {
                    throw new InvalidOperationException("XamlParserSetings is null,Parse method not pass the argument.");
                }
                IXamlErrorService xamlErrorService = _settings.XamlErrorService;
                if (xamlErrorService == null)
                {
                    throw new InvalidOperationException("IXamlErrorService not regist instance.");
                }
                return xamlErrorService;
            }
        }

        #endregion

        #region Parse Xaml

        public XamlDocument Parse(XmlTextReader xmlTextReader)
        {
            return Parse(xmlTextReader, new XamlParserSettings());
        }

        public XamlDocument Parse(XmlTextReader xmlTextReader, XamlParserSettings xamlParserSettings)
        {
            if (xmlTextReader == null)
            {
                throw new ArgumentNullException("xmlTextReader");
            }
            if (xamlParserSettings == null)
            {
                throw new ArgumentNullException("xamlParserSettings");
            }

            _settings = xamlParserSettings;

            try
            {
                XmlDocument xmlDoc = new PositionXmlDocument();
                xmlDoc.Load(xmlTextReader); //xml parse with the lineinfo
                return Parse(xmlDoc);
            }
            catch (XmlException ex)
            {
                XamlErrorService.ReportError(ex.Message, ex.LineNumber, ex.LinePosition);
            }

            return null;
        }

        private XamlDocument Parse(XmlDocument xmlDoc)
        {
            if (xmlDoc == null)
            {
                throw new ArgumentNullException("xmlDoc");
            }

            XamlDocument xamlDoc = new XamlDocument(xmlDoc, _settings);
            _document = xamlDoc;
            try
            {
                XamlObject root = ParseObject(xmlDoc.DocumentElement); //解析xaml成对象
                xamlDoc.ParseComplete(root);//解析完成的操作
            }
            catch (Exception ex)
            {
                ReportException(ex, xmlDoc.DocumentElement);
            }
            return xamlDoc;
        }

       
        #endregion

        #region ParseXmlElementOrAttribute


        /// <summary>
        /// Parse to object
        /// </summary>
        /// <param name="xmlElement"></param>
        /// <returns></returns>
        private XamlObject ParseObject(XmlElement xmlElement)
        {
            #region ParseTheObject

            //根据xmlnamespace和typename查找到相应的Type，如果找到elementType没有找到则找扩展
            Type elementType = XamlTypeFinder.GetClrType(xmlElement.NamespaceURI, xmlElement.LocalName);
            //Find ExtensionType
            if (elementType == null)
            {
                elementType = XamlTypeFinder.GetClrType(xmlElement.NamespaceURI, xmlElement.LocalName + "Extension");
                if (elementType == null)
                {
                    throw new XamlLoadException("Can't find type " + elementType);
                }
            }

            //记录当前的XamlObject为parentXamlObject以便在解析子控件时使用
            XmlSpace oldXmlSpace = _currentXmlSpace;
            XamlObject parentXamlObject = _currentXamlObject;

            if (xmlElement.HasAttribute("xml:space"))
            {
                _currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), xmlElement.GetAttribute("xml:space"), true);
            }

            //获取默认属性，ContentProperty CollectionProperty并且组装成XamlPropertyInfo
            XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType);

            //用来判断是用TextValue 还是用默认的构造函数初始化
            XamlTextValue initializeFromTextValueInsteadOfConstructor = null;

            //TODO 这个地方是不是调不到呢??
            if (defaultProperty == null)
            {
                int numberOfTextNodes = 0;
                bool onlyTextNodes = true;
                foreach (XmlNode childNode in xmlElement.ChildNodes)
                {
                    if (childNode.NodeType == XmlNodeType.Text)
                    {
                        numberOfTextNodes++;
                    }
                    else if (childNode.NodeType == XmlNodeType.Element)
                    {
                        onlyTextNodes = false;
                    }
                }

                if (onlyTextNodes && numberOfTextNodes == 1)
                {
                    foreach (XmlNode childNode in xmlElement.ChildNodes)
                    {
                        if (childNode.NodeType == XmlNodeType.Text)
                        {
                            initializeFromTextValueInsteadOfConstructor = (XamlTextValue)ParseValue(childNode);
                        }
                    }
                }
            }

            //CreateInstance
            object instance;

            if (initializeFromTextValueInsteadOfConstructor != null)
            {
                //用XamlTextValue结合TypeDescriptor来构造实例
                instance = TypeDescriptor.GetConverter(elementType).ConvertFromString(_document.GetTypeDescriptorContext(null), CultureInfo.InstalledUICulture, initializeFromTextValueInsteadOfConstructor.Text);
            }
            else
            {
                //用默认的构造函数来初始化(Activator.CreateInstance)
                instance = _settings.CreateInstanceCallback(elementType, new object[0]);
            }

            //这时候当前节点的元素实例已经构造出来，组成XamlObject (XamlDocument,currentXmlElement,instanceType,instance)
            XamlObject obj = new XamlObject(_document, xmlElement, elementType, instance);

            //如果是第一个父节点并且是依赖对象则给它添加namescope,至于这个Namescope有什么用，这里猜测到在写的时候可能用到
            if (parentXamlObject == null && obj.Instance is DependencyObject)
            {
                NameScope.SetNameScope((DependencyObject)obj.Instance, new NameScope());//??
            }

            //设置当前的XamlObject为刚造出来的那个，并且把前面的父亲赋值给他
            _currentXamlObject = obj;
            obj.ParentObject = parentXamlObject;

            #endregion

            #region BeginInit

            //如果这个实例是继承自ISupportInitialize，那么给予开始初始化的标记
            ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize;
            if (iSupportInitializeInstance != null)
            {
                iSupportInitializeInstance.BeginInit();
            }

            #endregion

            #region ParseTheAttribute

            foreach (XmlAttribute attribute in xmlElement.Attributes)
            {
                if (attribute.Value.StartsWith("clr-namespace", StringComparison.OrdinalIgnoreCase))
                {
                    //针对自己的代码加入Xaml的情况
                    //处理clr中的Assembly
                    var clrNamespace = attribute.Value.Split(new[] { ':', ';', '=' });
                    if (clrNamespace.Length == 4)
                    {
                        Assembly assembly = Assembly.Load(clrNamespace[3]);
                        if (assembly != null)
                        {
                            AssemblyLoader.RegisterAssembly(assembly);
                        }
                    }
                    else
                    {
                        Assembly assembly = Assembly.Load("");
                        if (assembly != null)
                        {
                            AssemblyLoader.RegisterAssembly(assembly);
                        }
                    }
                }

                //如果是xmlns属性......，则直接忽略掉
                if (attribute.NamespaceURI == XamlConstants.XmlnsNamespace)
                {
                    continue;
                }
                if (attribute.Name == "xml:space")
                {
                    continue;
                }
                if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace)
                {
                    continue;
                }
                //如果是正常的属性则开始解析属性
                ParseObjectAttribute(obj, attribute);
            }

            #endregion

            #region ParseTheContent

            if (!(obj.Instance is Style))
            {
                //开始解析当前节点的内容，即自节点
                ParseObjectContent(obj, xmlElement, defaultProperty, initializeFromTextValueInsteadOfConstructor);
            }

            #endregion

            #region EndInit

            if (iSupportInitializeInstance != null)
            {
                iSupportInitializeInstance.EndInit();
            }

            #endregion

            //递归结束后将当前XamlObject设置成亲的
            _currentXmlSpace = oldXmlSpace;
            _currentXamlObject = parentXamlObject;

            return obj;
        }

        /// <summary>
        /// 解析Content部分  TODO 对数据传递和结构尽心优化
        /// 先把子节点的Property都解析成XamlPropertyInfo XamlPropertyValue 然后组装成XamlProperty
        /// 最后object.add(new XamlProperty()) 给对象赋予相应的值
        /// </summary>
        /// <param name="obj">刚才初始化的XamlObject(XamlDocument,CurrentXmlElement,InstanceType,Type)</param>
        /// <param name="element">currentXmlElement</param>
        /// <param name="defaultProperty">默认的属性</param>
        /// <param name="initializeFromTextValueInsteadOfConstructor">是否用默认的构造函数构造</param>
        private void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
        {
            XamlPropertyValue setDefaultValueInfo = null;
            object defaultPropertyValue = null;
            XamlProperty defaultCollectionProperty = null;

            #region AddCollectionPropertyToObject

            if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty)
            {
                defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
                obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
            }

            #endregion

            #region ParseChildNode(Property or object)

            foreach (XmlNode childNode in GetNormalizedChildNodes(element))
            {
                if (defaultProperty != null && !defaultProperty.IsCollection)
                {
                    //这个地方的代码( defaultProperty.GetValue(obj.Instance); )根据SharpDevelop描述是没用的
                    for (; combinedNormalizedChildNodes > 0; combinedNormalizedChildNodes--)
                    {
                        defaultProperty.GetValue(obj.Instance);
                    }
                }

                XmlElement childElement = childNode as XmlElement;
                if (childElement != null)
                {
                    if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
                    {
                        continue;
                    }
                    if (ObjectChildElementIsPropertyElement(childElement))
                    {
                        //这个地方的代码( defaultProperty.GetValue(obj.Instance); )根据SharpDevelop描述是没用的
                        if (defaultProperty != null && defaultProperty.IsCollection)
                        {
                            defaultProperty.GetValue(obj.Instance);
                        }

                        ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
                        continue;
                    }
                }
                if (initializeFromTextValueInsteadOfConstructor != null)
                {
                    continue;
                }

                //解析值
                //-------进入递归-------//
                XamlPropertyValue childValue = ParseValue(childNode);
                //-------进入递归-------//

                //将值赋值到默认的属性上,如果默认属性是集合属性则向集合属性中添加解析出来的值,如果不是只有默认属性就给setDefaultValueInfo赋值
                if (childValue != null)
                {
                    if (defaultProperty != null && defaultProperty.IsCollection)
                    {
                        defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
                        CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
                    }
                    else
                    {
                        if (setDefaultValueInfo != null)
                        {
                            throw new XamlLoadException("default property may have only one value assigned.");
                        }
                        setDefaultValueInfo = childValue;
                    }
                }
            }


            #endregion

            #region AddNotCollectionPropertyToObject

            //这个地方的代码( defaultProperty.GetValue(obj.Instance); )根据SharpDevelop描述是没用的
            if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty)
            {
                defaultProperty.GetValue(obj.Instance);
            }

            //如果setDefaultValueInfo 不为空说明，这个属性不是集合熟悉
            if (setDefaultValueInfo != null)
            {
                if (defaultProperty == null)
                {
                    throw new XamlLoadException("This element don't have a default value,can't assign to it.");
                }
                obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueInfo));
            }

            #endregion
            
        }

        private void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement childElement, XamlPropertyInfo defaultProperty, object defaultPropertyValue)
        {
            XamlPropertyInfo propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, childElement.NamespaceURI, childElement.Name);
            bool valueWasSet = false;

            object collectionInstance = null;
            XamlProperty collectionProperty = null;
            if (propertyInfo.IsCollection)
            {
                if (defaultProperty != null && defaultProperty.FullQualifiedName == propertyInfo.FullQualifiedName)
                {
                    collectionInstance = defaultPropertyValue;
                    foreach (XamlProperty existing in obj.Properties)
                    {
                        if (existing.PropertyInfo == defaultProperty)
                        {
                            collectionProperty = existing;
                            break;
                        }
                    }
                }
                else
                {
                    collectionInstance = propertyInfo.GetValue(obj.Instance);
                }
                if (collectionProperty == null)
                {
                    obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo));
                }
                collectionProperty.ParserSetPropertyElement(childElement);
            }

            XmlSpace oldXmlSpace = _currentXmlSpace;
            if (childElement.HasAttribute("xml:space"))
            {
                _currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), childElement.GetAttribute("xml:space"), true);
            }
            foreach (XmlNode childNode in childElement.ChildNodes)
            {
                XamlPropertyValue childValue = ParseValue(childNode);
                if (childValue != null)
                {
                    if (propertyInfo.IsCollection)
                    {
                        CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue);
                        collectionProperty.ParserAddCollectionElement(childElement, childValue);
                    }
                    else
                    {
                        if (valueWasSet)
                        {
                            throw new XamlLoadException("non-collection property may have only one child element.");
                        }
                        valueWasSet = true;
                        XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue);
                        xp.ParserSetPropertyElement(childElement);
                        obj.AddProperty(xp);
                    }
                }
            }

            _currentXmlSpace = oldXmlSpace;
        }

        int combinedNormalizedChildNodes;

        /// <summary>
        /// 组织子节点
        /// </summary>
        /// <param name="element">这个还是一开始的总的XmlElement,一直传递到这</param>
        /// <returns></returns>
        private IEnumerable<XmlNode> GetNormalizedChildNodes(XmlElement element)
        {
            XmlNode node = element.FirstChild;
            while (node != null)
            {
                //往下分子节点,1.是文本节点2.是数据节点3.依然是正常的XmlElement节点 不过这些都属于XmlNode (Xml节点)
                XmlText text = node as XmlText;
                XmlCDataSection cData = node as XmlCDataSection;
                if (node.NodeType == XmlNodeType.SignificantWhitespace)
                {
                    text = element.OwnerDocument.CreateTextNode(node.Value);
                    element.ReplaceChild(text, node);
                    node = text;
                }

                if (text != null || cData != null)
                {
                    node = node.NextSibling;
                    while (node != null &&  (
                                            node.NodeType == XmlNodeType.Text
                                            || node.NodeType == XmlNodeType.CDATA
                                            || node.NodeType == XmlNodeType.SignificantWhitespace
                                            ))
                    {
                        //统计节点数目
                        combinedNormalizedChildNodes++;
                        //组织节点
                        if (text != null)
                        {
                            text.Value += node.Value;
                        }
                        else
                        {
                            cData.Value += node.Value;
                        }
                        XmlNode nodeToDelete = node;
                        node = node.NextSibling;
                        //这里将拿到的节点删除掉
                        element.RemoveChild(nodeToDelete);
                    }

                    if (text != null)
                    {
                        yield return text;
                    }
                    else
                    {
                        yield return cData;
                    }
                }
                else
                {
                    yield return node;
                    node = node.NextSibling;
                }
            }
        }

        /// <summary>
        /// 解析属性
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="attribute"></param>
        private void ParseObjectAttribute(XamlObject obj, XmlAttribute attribute)
        {
            try
            {
                ParseObjectAttribute(obj, attribute, true);
            }
            catch (System.Exception ex)
            {
                ReportException(ex, attribute);
            }
        }

        /// <summary>
        /// 解析XamlObject的属性
        /// </summary>
        /// <param name="obj">属性拥有者</param>
        /// <param name="attribue">属性节点</param>
        /// <param name="real"></param>
        private void ParseObjectAttribute(XamlObject obj, XmlAttribute attribue, bool real)
        {
            //获取属性信息
            XamlPropertyInfo propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, attribue);
            //获取值信息
            XamlPropertyValue value = null;
            string valueText = attribue.Value;
            if (valueText.StartsWith("{", StringComparison.Ordinal) && !valueText.StartsWith("{}", StringComparison.Ordinal))
            {
                //解析绑定的情况
            }
            else
            {
                if (real)
                {
                    value = new XamlTextValue(obj.OwnerDocument, attribue);
                }
                else
                {
                    value = new XamlTextValue(obj.OwnerDocument, valueText);
                }
            }
            //组装成XamlProeprty
            XamlProperty property = new XamlProperty(obj, propertyInfo, value);
            obj.AddProperty(property);
        }

        /// <summary>
        /// 从属性的文本中生成XamlObject
        /// </summary>
        /// <param name="Text"></param>
        /// <param name="targetProperty"></param>
        /// <param name="xamlObject"></param>
        /// <returns></returns>
        public object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject xamlObject)
        {
            Debug.WriteLine("valueText:" + valueText);
            //Converts the given text to an object, using the specified context. 
            return targetProperty.TypeConverter.ConvertFromString(xamlObject.OwnerDocument.GetTypeDescriptorContext(xamlObject), CultureInfo.InvariantCulture, valueText);
        }

        
        #endregion

        #region ParserValue

        /// <summary>
        /// 解析元素的子节点
        /// </summary>
        /// <param name="childNode">子节点</param>
        /// <returns></returns>
        private XamlPropertyValue ParseValue(XmlNode childNode)
        {
            try
            {
                return ParseValueCore(childNode);
            }
            catch (System.Exception ex)
            {
                ReportException(ex, childNode);
            }
            return null;
        }


        /// <summary>
        /// 解析子节点核心方法
        /// 1.普通的文本节点2.数据集合节点3.仍然是元素节点
        /// </summary>
        /// <param name="childNode"></param>
        /// <returns></returns>
        private XamlPropertyValue ParseValueCore(XmlNode childNode)
        {
            XmlText childText = childNode as XmlText;
            if (childText != null)
            {
                return new XamlTextValue(_document, childText, _currentXmlSpace);
            }
            XmlCDataSection cData = childNode as XmlCDataSection;
            if (cData != null)
            {
                return new XamlTextValue(_document, cData, _currentXmlSpace);
            }
            XmlElement element = childNode as XmlElement;
            if (element != null)
            {
                return ParseObject(element);
            }
            return null;
        }

        #endregion
     
        #region FindProperty

        /// <summary>
        /// 获取默认属性
        /// </summary>
        /// <param name="elementType"></param>
        /// <returns></returns>
        private XamlPropertyInfo GetDefaultProperty(Type elementType)
        {
            foreach (ContentPropertyAttribute cpa in elementType.GetCustomAttributes(typeof(ContentPropertyAttribute),true))
            {
                return FindProperty(null, elementType, cpa.Name);
            }
            return null;
        }
       
        /// <summary>
        /// 总体获取属性
        /// </summary>
        /// <param name="component"></param>
        /// <param name="componentType"></param>
        /// <param name="attribute"></param>
        /// <returns></returns>
        private XamlPropertyInfo GetPropertyInfo(object component, Type componentType, XmlAttribute attribute)
        {
            if (attribute.LocalName.Contains("."))
            {
                return GetPropertyInfo(component, componentType, GetAttributeNamespace(attribute), attribute.LocalName);
            }
            else
            {
                return FindProperty(component, componentType, attribute.LocalName);
            }
        }

        /// <summary>
        /// 查找属性
        /// 主要用来查找 普通属性，依赖属性，事件属性
        /// </summary>
        /// <param name="component">实例</param>
        /// <param name="componentType">实例类型</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns></returns>
        public XamlPropertyInfo FindProperty(object component, Type componentType, string propertyName)
        {
            //找到对应的属性的描述
            PropertyDescriptorCollection pdc;
            if (component != null)
            {
                pdc = TypeDescriptor.GetProperties(component);
            }
            else
            {
                pdc = TypeDescriptor.GetProperties(componentType);
            }

            PropertyDescriptor propertyDescriptor = pdc[propertyName];

            //is normal property exists,then find the attached property

            if (propertyDescriptor != null)
            {
                //查找普通的属性
                return new XamlNormalPropertyInfo(propertyDescriptor);
            }
            else
            {
                //查找依赖属性
                XamlPropertyInfo xamlPropertyInfo = TryFindAttachedProperty(componentType, propertyName);
                if (xamlPropertyInfo != null)
                {
                    return xamlPropertyInfo;
                }
            }

            //EventProperty
            //查找事件
            EventDescriptorCollection events;
            if (component != null)
            {
                events = TypeDescriptor.GetEvents(componentType);
            }
            else
            {
                events = TypeDescriptor.GetEvents(component);
            }

            EventDescriptor eventDescriptor = events[propertyName];
            if (eventDescriptor != null)
            {
                return new XamlEventPropertyInfo(eventDescriptor);
            }
            //如果都没有找到则抛出异常
            throw new XamlLoadException("Property" + propertyName + "not found.");
        }

        /// <summary>
        /// 对于属性中包含.的情况
        /// </summary>
        /// <param name="component"></param>
        /// <param name="componentType"></param>
        /// <param name="xmlNamespace"></param>
        /// <param name="localName"></param>
        /// <returns></returns>
        public XamlPropertyInfo GetPropertyInfo(object component, Type componentType, string xmlNamespace, string localName)
        {
            string typeName,propertyName;
            //分割出相应的类型和属性名称
            SplitQualifiedIdentifier(localName, out typeName, out propertyName);
            //获取这个属性所对应的类型
            Type propertyOfType = XamlTypeFinder.GetClrType(xmlNamespace, typeName);
            if (componentType == propertyOfType || propertyOfType.IsAssignableFrom(componentType))
            {
                return FindProperty(component, componentType, propertyName);
            }
            else
            {
                //根据属性类型找到依赖属性
                return FindAttachedProperty(propertyOfType, propertyName);
            }
        }
        /// <summary>
        /// 获取依赖属性的XamlPropertyInfo
        /// </summary>
        /// <param name="componentType"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        private XamlPropertyInfo FindAttachedProperty(Type propertyOfType, string propertyName)
        {
            XamlPropertyInfo pi = TryFindAttachedProperty(propertyOfType, propertyName);
            if (pi != null)
            {
                return pi;
            }
            else
            {
                throw new XamlLoadException("attached property" + propertyOfType.Name + "." + propertyName + "not found.");
            }
        }

        /// <summary>
        /// 查找依赖属性
        /// </summary>
        /// <param name="componentType"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        private XamlPropertyInfo TryFindAttachedProperty(Type propertyOfType, string propertyName)
        {
            MethodInfo getMethod = propertyOfType.GetMethod("Get" + propertyName, BindingFlags.Public | BindingFlags.Static);
            MethodInfo setMethod = propertyOfType.GetMethod("Set" + propertyName, BindingFlags.Public | BindingFlags.Static);

            if (getMethod != null && setMethod != null)
            {
                FieldInfo fieldInfo = propertyOfType.GetField(propertyName + "Property", BindingFlags.Public | BindingFlags.Static);
                if (fieldInfo != null && fieldInfo.FieldType == typeof(DependencyProperty))
                {
                    return new XamlDependencyPropertyInfo((DependencyProperty)fieldInfo.GetValue(null), true);
                }
            }
            return null;
        }


        #endregion

        #region Util

        /// <summary>
        /// 根据XmlAttributel来获取属性的名字空间
        /// </summary>
        /// <param name="attribute"></param>
        /// <returns></returns>
        private string GetAttributeNamespace(XmlAttribute attribute)
        {
            if (attribute.NamespaceURI.Length > 0)
            {
                return attribute.NamespaceURI;
            }
            else
            {
                return attribute.OwnerElement.GetNamespaceOfPrefix("");
            }
        }

        /// <summary>
        /// 判断子元素是属性元素
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        private bool ObjectChildElementIsPropertyElement(XmlElement element)
        {
            return element.LocalName.Contains(".");
        }

        /// <summary>
        /// 拆分出属性拥有者和对应的依赖属性名称
        /// </summary>
        /// <param name="localName"></param>
        /// <param name="typeName"></param>
        /// <param name="propertyName"></param>
        private void SplitQualifiedIdentifier(string localName, out string typeName, out string propertyName)
        {
            int pos = localName.IndexOf('.');
            if (pos < 0)
            {
                throw new ArgumentException("SplitQualifiedIdentifier-post < 0");
            }
            typeName = localName.Substring(0, pos);
            propertyName = localName.Substring(pos + 1);
        }

        #endregion

        #region XamlParseException

        /// <summary>
        /// 异常处理
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="node">real is PositionXmlElement</param>
        private void ReportException(Exception ex, XmlNode node)
        {
            IXmlLineInfo xmlLineInfo = node as IXmlLineInfo;
            if (xmlLineInfo != null)
            {
                XamlErrorService.ReportError(ex.Message, xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
            }
            else
            {
                XamlErrorService.ReportError(ex.Message, 0, 0);
            }
            if (_currentXamlObject != null)
            {
                _currentXamlObject.HasErrors = true;
            }
        }

        #endregion
    }
}
